!-------------------------------------------------------------LICENSE--------------------------------------------------------------!
!                                                                                                                                  !
!The MAP code is written in Fortran language for magnetohydrodynamics (MHD) calculation with the adaptive mesh refinement (AMR)    !
!and Message Passing Interface (MPI) parallelization.                                                                              !
!                                                                                                                                  !
!Copyright (C) 2012                                                                                                                !
!Ronglin Jiang                                                                                                                     !
!rljiang@ssc.net.cn                                                                                                                !
!585 Guoshoujing Road. Pudong, Shanghai, P.R.C. 201203                                                                             !
!                                                                                                                                  !
!This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License         !
!as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.             !
!                                                                                                                                  !
!This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of    !
!MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.                        !
!                                                                                                                                  !
!You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software     !
!Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.                                                   !
!                                                                                                                                  !
!-------------------------------------------------------------LICENSE--------------------------------------------------------------!

!==================================================================================================================================|
subroutine neigh_shareblock (base, buffer_send_x, buffer_send_y, buffer_recv_x, buffer_recv_y,                                     &
   n_var, ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, az_flag, po_flag)
!==================================================================================================================================|

   use parameters
   use block_define
   implicit none

   integer(4), intent(in) :: n_var
   logical(4), optional :: ro_flag, mx_flag, my_flag, mz_flag, bx_flag, by_flag, bz_flag, en_flag, az_flag, po_flag
   real(8), intent(inout) :: buffer_send_x(n_var, ng + 1, ny_block, shareblock_size_send_x)
   real(8), intent(inout) :: buffer_send_y(n_var, nx_block, ng + 1, shareblock_size_send_y)
   real(8), intent(inout) :: buffer_recv_x(n_var, ng + 1, ny_block, shareblock_size_recv_x)
   real(8), intent(inout) :: buffer_recv_y(n_var, nx_block, ng + 1, shareblock_size_recv_y)
   type(block), pointer, intent(in) :: base

   integer(4) :: i, j, i_cpu, i_cpu_p1, i_neigh, j_neigh, i_level, i_request, i_c, j_c, i_var
   integer(4) :: i_recv, i_send, cpu_index_x, cpu_index_y
   integer(4) :: i_block, j_block, i_start, j_start, i_end, j_end, start_x, start_y
   integer(4) :: n_request, n_neighs_cpu, pos_x, pos_y
   integer(4), dimension(:), allocatable :: request
   integer(4), dimension(:, :), allocatable :: request_status
   type(block), pointer :: current, child

!----------------------------------------------------------------------------------------------------------------------------------|
!  var send flag
!----------------------------------------------------------------------------------------------------------------------------------|
   if (n_var .le. 0) then
      write (*, *)
      write (*, *) 'Warning: no variable will be updated.'
      write (*, *)
   endif

!----------------------------------------------------------------------------------------------------------------------------------|
   n_request = count (n_neighs_shareblock_sendrecv_x(:, cpu_id_p1) .gt. 0) +                                                       &
               count (n_neighs_shareblock_sendrecv_x(cpu_id_p1, :) .gt. 0) +                                                       &
               count (n_neighs_shareblock_sendrecv_y(:, cpu_id_p1) .gt. 0) +                                                       &
               count (n_neighs_shareblock_sendrecv_y(cpu_id_p1, :) .gt. 0)
   allocate (request(n_request * 2), request_status(mpi_status_size, n_request * 2))

!----------------------------------------------------------------------------------------------------------------------------------|
!  collect information for sending data
!----------------------------------------------------------------------------------------------------------------------------------|
   cpu_index_x = 1
   cpu_index_y = 1
   do i_cpu = 0, cpu_number - 1

      if (i_cpu .eq. cpu_id) cycle
      i_cpu_p1 = i_cpu + 1

      n_neighs_cpu = n_neighs_shareblock_sendrecv_x(i_cpu_p1, cpu_id_p1)
      do i_send = 1, n_neighs_cpu
         i_level = 1
         current => base
         do while (neighs_shareblock_info_send_x(i_level * 2 - 1, i_send, i_cpu_p1) .ne. 0)
            pos_x = neighs_shareblock_info_send_x(i_level * 2 - 1, i_send, i_cpu_p1)
            pos_y = neighs_shareblock_info_send_x(i_level * 2, i_send, i_cpu_p1)
            current => current%child(pos_x, pos_y)%pblock
            i_level = i_level + 1
            if (i_level .gt. n_levels) exit
         enddo

         i_neigh = neighs_shareblock_info_send_x(n_d_l + 1, i_send, i_cpu_p1)
         if (i_neigh .eq. 1) i_neigh = nx_block - ng - 1
         if (i_neigh .eq. -1) i_neigh = 0

         i_end = ng + 1
         do j = 1, ny_block
         do i = 1, i_end
            i_c = i_neigh + i
            i_var = 0
            if (present(ro_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%ro(i_c, j)
            endif
            if (present(mx_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%mx(i_c, j)
            endif
            if (present(my_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%my(i_c, j)
            endif
            if (present(mz_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%mz(i_c, j)
            endif
            if (present(bx_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%bx(i_c, j)
            endif
            if (present(by_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%by(i_c, j)
            endif
            if (present(bz_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%bz(i_c, j)
            endif
            if (present(en_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%en(i_c, j)
            endif
            if (present(az_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%az(i_c, j)
            endif
            if (present(po_flag)) then
               i_var = i_var + 1
               buffer_send_x(i_var, i, j, cpu_index_x) = current%po(i_c, j)
            endif
         enddo
         enddo
         cpu_index_x = cpu_index_x + 1
      enddo

      n_neighs_cpu = n_neighs_shareblock_sendrecv_y(i_cpu_p1, cpu_id_p1)
      do i_send = 1, n_neighs_cpu
         i_level = 1
         current => base
         do while (neighs_shareblock_info_send_y(i_level * 2 - 1, i_send, i_cpu_p1) .ne. 0)
            pos_x = neighs_shareblock_info_send_y(i_level * 2 - 1, i_send, i_cpu_p1)
            pos_y = neighs_shareblock_info_send_y(i_level * 2, i_send, i_cpu_p1)
            current => current%child(pos_x, pos_y)%pblock
            i_level = i_level + 1
            if (i_level .gt. n_levels) exit
         enddo

         j_neigh = neighs_shareblock_info_send_y(n_d_l + 1, i_send, i_cpu_p1)
         if (j_neigh .eq. 1) j_neigh = ny_block - ng - 1
         if (j_neigh .eq. -1) j_neigh = 0

         j_end = ng + 1
         do j = 1, j_end
            j_c = j_neigh + j
            do i = 1, nx_block
               i_var = 0
               if (present(ro_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%ro(i, j_c)
               endif
               if (present(mx_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%mx(i, j_c)
               endif
               if (present(my_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%my(i, j_c)
               endif
               if (present(mz_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%mz(i, j_c)
               endif
               if (present(bx_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%bx(i, j_c)
               endif
               if (present(by_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%by(i, j_c)
               endif
               if (present(bz_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%bz(i, j_c)
               endif
               if (present(en_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%en(i, j_c)
               endif
               if (present(az_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%az(i, j_c)
               endif
               if (present(po_flag)) then
                  i_var = i_var + 1
                  buffer_send_y(i_var, i, j, cpu_index_y) = current%po(i, j_c)
               endif
            enddo
         enddo
         cpu_index_y = cpu_index_y + 1
      enddo

   enddo

!----------------------------------------------------------------------------------------------------------------------------------|
!  send data to other cpu
!----------------------------------------------------------------------------------------------------------------------------------|
   i_request = 0
   cpu_index_x = 1
   cpu_index_y = 1
   do i_cpu = 0, cpu_number - 1

      if (cpu_id .eq. i_cpu) cycle
      i_cpu_p1 = i_cpu + 1

      n_neighs_cpu = n_neighs_shareblock_sendrecv_x(i_cpu_p1, cpu_id_p1)
      if (n_neighs_cpu .ne. 0) then
         i_request = i_request + 1
         call mpi_isend(neighs_shareblock_info_send_x(:, :, i_cpu_p1), (n_d_l + 1) * n_neighs_cpu,                                 &
            mpi_integer4, i_cpu, tag_int + 3, mpi_comm_world, request(i_request), error)
         i_request = i_request + 1
         call mpi_isend(buffer_send_x(:, :, :, cpu_index_x), n_var * (ng + 1) * ny_block * n_neighs_cpu,                           &
            mpi_real8, i_cpu, tag_var + 3, mpi_comm_world, request(i_request), error)
         cpu_index_x = cpu_index_x + n_neighs_cpu
      endif

      n_neighs_cpu = n_neighs_shareblock_sendrecv_y(i_cpu_p1, cpu_id_p1)
      if (n_neighs_cpu .ne. 0) then
         i_request = i_request + 1
         call mpi_isend(neighs_shareblock_info_send_y(:, :, i_cpu_p1), (n_d_l + 1) * n_neighs_cpu,                                 &
            mpi_integer4, i_cpu, tag_int + 4, mpi_comm_world, request(i_request), error)
         i_request = i_request + 1
         call mpi_isend(buffer_send_y(:, :, :, cpu_index_y), n_var * (ng + 1) * nx_block * n_neighs_cpu,                           &
            mpi_real8, i_cpu, tag_var + 4, mpi_comm_world, request(i_request), error)
         cpu_index_y = cpu_index_y + n_neighs_cpu
      endif

   enddo

!----------------------------------------------------------------------------------------------------------------------------------|
!  receive data from other cpu
!----------------------------------------------------------------------------------------------------------------------------------|
   cpu_index_x = 1
   cpu_index_y = 1
   do i_cpu = 0, cpu_number - 1
      if (cpu_id .eq. i_cpu) cycle
      i_cpu_p1 = i_cpu + 1

      n_neighs_cpu = n_neighs_shareblock_sendrecv_x(cpu_id_p1, i_cpu_p1)
      if (n_neighs_cpu .ne. 0) then
         i_request = i_request + 1
         call mpi_irecv(neighs_shareblock_info_recv_x(:, :, i_cpu_p1), (n_d_l + 1) * n_neighs_cpu,                                 &
            mpi_integer4, i_cpu, tag_int + 3, mpi_comm_world, request(i_request), error)
         i_request = i_request + 1
         call mpi_irecv(buffer_recv_x(:, :, :, cpu_index_x), n_var * (ng + 1) * ny_block * n_neighs_cpu,                           &
            mpi_real8, i_cpu, tag_var + 3, mpi_comm_world, request(i_request), error)
         cpu_index_x = cpu_index_x + n_neighs_cpu
      endif

      n_neighs_cpu = n_neighs_shareblock_sendrecv_y(cpu_id_p1, i_cpu_p1)
      if (n_neighs_cpu .ne. 0) then
         i_request = i_request + 1
         call mpi_irecv(neighs_shareblock_info_recv_y(:, :, i_cpu_p1), (n_d_l + 1) * n_neighs_cpu,                                 &
            mpi_integer4, i_cpu, tag_int + 4, mpi_comm_world, request(i_request), error)
         i_request = i_request + 1
         call mpi_irecv(buffer_recv_y(:, :, :, cpu_index_y), n_var * (ng + 1) * nx_block * n_neighs_cpu,                           &
            mpi_real8, i_cpu, tag_var + 4, mpi_comm_world, request(i_request), error)
         cpu_index_y = cpu_index_y + n_neighs_cpu
      endif

   enddo

!----------------------------------------------------------------------------------------------------------------------------------|
!  waiting for mpi communication
!----------------------------------------------------------------------------------------------------------------------------------|
   call mpi_waitall (size (request), request, request_status, error)

!----------------------------------------------------------------------------------------------------------------------------------|
!  update neigh blocks
!----------------------------------------------------------------------------------------------------------------------------------|
   cpu_index_x = 1
   cpu_index_y = 1
   do i_cpu = 0, cpu_number - 1

      if (i_cpu .eq. cpu_id) cycle
      i_cpu_p1 = i_cpu + 1

      n_neighs_cpu = n_neighs_shareblock_sendrecv_x(cpu_id_p1, i_cpu_p1)
      do i_recv = 1, n_neighs_cpu
         i_level = 1
         current => base
         do while (neighs_shareblock_info_recv_x(i_level * 2 - 1, i_recv, i_cpu_p1) .ne. 0)
            pos_x = neighs_shareblock_info_recv_x(i_level * 2 - 1, i_recv, i_cpu_p1)
            pos_y = neighs_shareblock_info_recv_x(i_level * 2, i_recv, i_cpu_p1)
            current => current%child(pos_x, pos_y)%pblock
            i_level = i_level + 1
            if (i_level .gt. n_levels) exit
         enddo

         i_neigh = neighs_shareblock_info_recv_x(n_d_l + 1, i_recv, i_cpu_p1)

!         i_end = ng + 1
!         do j = 1, ny_block
!         do i = 1, i_end
!            i_c = i_neigh + i
!            i_var = 0
!            if (present(ro_flag)) then
!               i_var = i_var + 1
!               current%ro(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!            if (present(mx_flag)) then
!               i_var = i_var + 1
!               current%mx(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!            if (present(my_flag)) then
!               i_var = i_var + 1
!               current%my(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!            if (present(mz_flag)) then
!               i_var = i_var + 1
!               current%mz(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!            if (present(bx_flag)) then
!               i_var = i_var + 1
!               current%bx(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!            if (present(by_flag)) then
!               i_var = i_var + 1
!               current%by(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!            if (present(bz_flag)) then
!               i_var = i_var + 1
!               current%bz(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!            if (present(en_flag)) then
!               i_var = i_var + 1
!               current%en(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!            if (present(az_flag)) then
!               i_var = i_var + 1
!               current%az(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!            if (present(po_flag)) then
!               i_var = i_var + 1
!               current%po(i_c, j) = buffer_recv_x(i_var, i, j, cpu_index_x)
!            endif
!         enddo
!         enddo

         if (i_neigh .eq. 1) then
            i_block = 2
            i_start = nx_block - ng + 1
            i_end = nx_block
            start_x = ratio + 1
         endif
         if (i_neigh .eq. -1) then
            i_block = 1
            i_start = 1
            i_end = ng
            start_x = ng * ratio - ng + 1
         endif

         do j_block = 1, ratio
            child => current%child(i_block, j_block)%pblock
            if (child%cpu_id .eq. cpu_id) then
               start_y =  ng * ratio - ng + 1 + ny_no_bnd * (j_block - 1)
               if (present(ro_flag)) call block_interpolate(child%ro(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(1, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
               if (present(mx_flag)) call block_interpolate(child%mx(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(2, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
               if (present(my_flag)) call block_interpolate(child%my(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(3, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
               if (present(mz_flag)) call block_interpolate(child%mz(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(4, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
               if (present(bx_flag)) call block_interpolate(child%bx(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(5, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
               if (present(by_flag)) call block_interpolate(child%by(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(6, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
               if (present(bz_flag)) call block_interpolate(child%bz(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(7, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
               if (present(en_flag)) call block_interpolate(child%en(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(8, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
               if (present(az_flag)) call block_interpolate(child%az(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(9, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
               if (present(po_flag)) call block_interpolate(child%po(i_start : i_end, :), ng, ny_block,                     &
                  buffer_recv_x(10, :, :, cpu_index_x), ng + 1, ny_block, start_x, start_y, ratio)
            endif
         enddo

         cpu_index_x = cpu_index_x + 1
      enddo

      n_neighs_cpu = n_neighs_shareblock_sendrecv_y(cpu_id_p1, i_cpu_p1)
      do i_recv = 1, n_neighs_cpu
         i_level = 1
         current => base
         do while (neighs_shareblock_info_recv_y(i_level * 2 - 1, i_recv, i_cpu_p1) .ne. 0)
            pos_x = neighs_shareblock_info_recv_y(i_level * 2 - 1, i_recv, i_cpu_p1)
            pos_y = neighs_shareblock_info_recv_y(i_level * 2, i_recv, i_cpu_p1)
            current => current%child(pos_x, pos_y)%pblock
            i_level = i_level + 1
            if (i_level .gt. n_levels) exit
         enddo

         j_neigh = neighs_shareblock_info_recv_y(n_d_l + 1, i_recv, i_cpu_p1)
!         if (j_neigh .eq. 1) j_neigh = ny_block - ng - 1
!         if (j_neigh .eq. -1) j_neigh = 0

!         j_end = ng + 1
!         do j = 1, j_end
!            j_c = j_neigh + j
!            do i = 1, nx_block
!               i_var = 0
!               if (present(ro_flag)) then
!                  i_var = i_var + 1
!                  current%ro(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!               if (present(mx_flag)) then
!                  i_var = i_var + 1
!                  current%mx(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!               if (present(my_flag)) then
!                  i_var = i_var + 1
!                  current%my(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!               if (present(mz_flag)) then
!                  i_var = i_var + 1
!                  current%mz(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!               if (present(bx_flag)) then
!                  i_var = i_var + 1
!                  current%bx(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!               if (present(by_flag)) then
!                  i_var = i_var + 1
!                  current%by(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!               if (present(bz_flag)) then
!                  i_var = i_var + 1
!                  current%bz(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!               if (present(en_flag)) then
!                  i_var = i_var + 1
!                  current%en(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!               if (present(az_flag)) then
!                  i_var = i_var + 1
!                  current%az(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!               if (present(po_flag)) then
!                  i_var = i_var + 1
!                  current%po(i, j_c) = buffer_recv_y(i_var, i, j, cpu_index_y)
!               endif
!            enddo
!         enddo

         if (j_neigh .eq. 1) then
            j_block = 2
            j_start = ny_block - ng + 1
            j_end = ny_block
            start_y = ratio + 1
         endif
         if (j_neigh .eq. -1) then
            j_block = 1
            j_start = 1
            j_end = ng
            start_y = ng * ratio - ng + 1
         endif

         do i_block = 1, ratio
            child => current%child(i_block, j_block)%pblock
            if (child%cpu_id .eq. cpu_id) then
               start_x =  ng * ratio - ng + 1 + nx_no_bnd * (i_block - 1)
               if (present(ro_flag)) call block_interpolate(child%ro(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(1, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
               if (present(mx_flag)) call block_interpolate(child%mx(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(2, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
               if (present(my_flag)) call block_interpolate(child%my(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(3, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
               if (present(mz_flag)) call block_interpolate(child%mz(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(4, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
               if (present(bx_flag)) call block_interpolate(child%bx(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(5, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
               if (present(by_flag)) call block_interpolate(child%by(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(6, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
               if (present(bz_flag)) call block_interpolate(child%bz(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(7, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
               if (present(en_flag)) call block_interpolate(child%en(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(8, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
               if (present(az_flag)) call block_interpolate(child%az(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(9, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
               if (present(po_flag)) call block_interpolate(child%po(:, j_start : i_end), nx_block, ng,                     &
                  buffer_recv_y(10, :, :, cpu_index_y), ny_block, ng + 1, start_x, start_y, ratio)
            endif
         enddo

         cpu_index_y = cpu_index_y + 1
      enddo

   enddo

   deallocate (request, request_status)

!----------------------------------------------------------------------------------------------------------------------------------|
   return
end subroutine neigh_shareblock
